import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router, ActivatedRoute } from '@angular/router';

import { RuleVO } from '../../model/RuleVO';
import { RuleMetricConditionVO } from '../../model/RuleMetricConditionVO';
import { WorkingTimeWindowVO } from '../../model/WorkingTimeWindowVO';

@Component({
  selector: 'app-addRule',
  templateUrl: './addRule.component.html',
  styleUrls: ['./addRule.component.css'],
})
export class AddRuleComponent implements OnInit {
  ruleVO: RuleVO = new RuleVO();

  ruleId: string | null = null;

  ruleName: string | null = null;

  ruleState: string = '激活';

  windowType: string = '小时';

  windowSize: number | null = 1;

  waterMark: number | null = 30;

  selectedMetric = '';
  metrics = [];
  nzFilterOption = () => true;

  tagsOfMetric: string[] = [];
  tags: Array<{ tagKey: string; tagValue: string }> = [];
  tagValues: string[] = [];

  metricTagIndex = 0;
  metricTags: any = [];

  workingTimeWindows: any = [];

  constructor(
    private httpClient: HttpClient,
    private route: ActivatedRoute,
    private router: Router
  ) { }

  ngOnInit() {
    let id = this.route.snapshot.params.id;
    if (id === '-1') {
      let beginTime: Date = new Date();
      let endTime: Date = new Date();
      beginTime.setHours(0, 0, 0, 0);
      endTime.setHours(23, 59, 59, 999);
      this.workingTimeWindows.push({
        beginTime: beginTime,
        endTime: endTime
      });

      return;
    }
    this.ruleId = id;

    this.httpClient
      .get<RuleVO>('/api/v1/stream/rule/' + id, {})
      .subscribe((result: RuleVO) => {
        console.log(result);
        this.ruleVO = result;

        this.ruleName = this.ruleVO.name;
        this.ruleState = this.ruleVO.ruleState;
        this.windowType = this.ruleVO.windowType;
        this.windowSize =
          this.ruleVO.windowSize == null ? -1 : this.ruleVO.windowSize;
        this.waterMark =
          this.ruleVO.waterMark == null ? -1 : this.ruleVO.waterMark;

        let that = this;
        this.ruleVO.ruleMetricConditionVOs.forEach(function (conditionVO) {
          that.metricTags.push({
            name: conditionVO.metric,
            aggregatorFunctionType: conditionVO.aggregatorFunctionType,
            limitOperatorType: conditionVO.limitOperatorType,
            limit: conditionVO.limit,
          });
        });

        this.ruleVO.workingTimeWindowVOs.forEach(function (workingTimeWindowVO) {
          let beginTime: Date = new Date();
          beginTime.setTime(workingTimeWindowVO.beginTime);
          let endTime: Date = new Date();
          endTime.setTime(workingTimeWindowVO.endTime);
          that.workingTimeWindows.push({
            beginTime: beginTime,
            endTime: endTime
          });
        });

        Object.keys(this.ruleVO.tags).forEach((key) => {
          let tagKey: string = key;
          let tagValues: [] = this.ruleVO.tags[key];
          that.tagsOfMetric.push(tagKey);

          tagValues.forEach(function (tagValue: any) {
            that.tagValues.push(tagValue);
            that.tags.push({ tagKey: tagKey, tagValue: tagValue });
          });
        });
        console.log(this.tags);
      });

  }

  onMetricSerach(value: string): void {
    if (value === '') {
      return;
    }
    let url = '/api/metricTag/queryMetric';
    let body: any = {};
    body['metric'] = value;
    this.httpClient.post(url, body, {}).subscribe((data: any) => {
      this.metrics = data;
    });
  }

  addMetricTag(): void {
    let url = '/api/metricTag/queryTagKeyOfMetric';
    let body: any = {};
    body['metric'] = this.selectedMetric;
    this.httpClient.post(url, body, {}).subscribe((data: any) => {
      this.tagsOfMetric = data;

      let exist: boolean = false;
      let that = this;

      this.metricTags.forEach(function (metricTag: any) {
        if (metricTag.name === that.selectedMetric) {
          exist = true;
        }
      });

      if (!exist) {
        this.metricTags.push({
          name: this.selectedMetric,
          aggregatorFunctionType: '平均值',
          limitOperatorType: '>=',
          limit: 0.0,
        });
      }

      this.metricTagIndex = this.metricTags.length - 1;
    });
  }

  closeMetricTag({ index }: { index: number }): void {
    this.metricTags.splice(index, 1);
  }

  queryTagValueOfMetric(index: number, value: string) {
    console.log(this.selectedMetric);
    if (this.selectedMetric === '') {
      return;
    }
    let url = '/api/metricTag/queryTagValueOfMetric';
    let body: any = {};
    body['metric'] = this.selectedMetric;
    body['tagKey'] = this.tags[index].tagKey;
    body['tagValue'] = value;
    this.httpClient.post(url, body, {}).subscribe((data: any) => {
      this.tagValues = data;
    });
  }

  addTag(e?: MouseEvent): void {
    if (e) {
      e.preventDefault();
    }
    this.tags.push({ tagKey: '', tagValue: '' });
  }

  deleteTag(index: number, e: MouseEvent): void {
    if (e) {
      e.preventDefault();
    }
    this.tags.splice(index, 1);
  }

  addWorkingTimeWindow(e?: MouseEvent): void {
    if (e) {
      e.preventDefault();
    }
    this.workingTimeWindows.push({});
  }

  deleteWorkingTimeWindow(index: number, e: MouseEvent): void {
    if (e) {
      e.preventDefault();
    }
    this.workingTimeWindows.splice(index, 1);
  }

  onCreate(): void {
    this.ruleVO = new RuleVO();

    this.ruleVO.id = this.ruleId == null ? '' : this.ruleId;

    let that = this;

    this.ruleVO.name = this.ruleName == null ? '' : this.ruleName;
    this.ruleVO.ruleState = this.ruleState;
    this.ruleVO.windowType = this.windowType;
    this.ruleVO.windowSize = this.windowSize == null ? 1 : this.windowSize;
    this.ruleVO.waterMark = this.waterMark == null ? 1 : this.waterMark;

    this.tags.forEach(function (tag) {
      if (tag.tagKey !== '' && tag.tagValue !== '') {
        if (!that.ruleVO.tags[tag.tagKey]) {
          that.ruleVO.tags[tag.tagKey] = [tag.tagValue];
        } else if (that.ruleVO.tags[tag.tagKey].indexOf(tag.tagValue) == -1) {
          that.ruleVO.tags[tag.tagKey].push(tag.tagValue);
        }
      }
    });

    this.metricTags.forEach(function (metricTag: any) {
      let conditionVO: RuleMetricConditionVO = new RuleMetricConditionVO();
      conditionVO.metric = metricTag.name;
      conditionVO.aggregatorFunctionType = metricTag.aggregatorFunctionType;
      conditionVO.limitOperatorType = metricTag.limitOperatorType;
      conditionVO.limit = metricTag.limit;

      that.ruleVO.ruleMetricConditionVOs.push(conditionVO);
    });

    this.workingTimeWindows.forEach(function (workingTimeWindow: any) {
      let workingTimeWindowVO: WorkingTimeWindowVO = new WorkingTimeWindowVO();
      workingTimeWindow.beginTime.setMilliseconds(0);
      workingTimeWindow.endTime.setMilliseconds(999);
      workingTimeWindowVO.beginTime = workingTimeWindow.beginTime.getTime();
      workingTimeWindowVO.endTime = workingTimeWindow.endTime.getTime();

      that.ruleVO.workingTimeWindowVOs.push(workingTimeWindowVO);
    });

    console.log(this.ruleVO);

    this.httpClient
      .post<RuleVO[]>('/api/v1/stream/rule', this.ruleVO, {})
      .subscribe((result: RuleVO[]) => {
        console.log(result);
        this.router.navigate(['/ruleQuery']);
      });
  }
}
